package net.towee.client.com.stuff.presenter;

import com.google.common.base.Strings;
import com.google.common.base.Preconditions;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.inject.Inject;

import net.towee.client.com.stuff.GroupRolesShower;
import net.towee.client.event.RoleOperationEvent;
import net.towee.client.event.RoleOperationEvent.HasRoleOperationHandlers;
import net.towee.client.event.RoleOperationEvent.RoleOperationHandler;
import net.towee.client.managers.GroupsManager;
import net.towee.client.managers.RolesManager;
import net.towee.model.account.Role;
import net.towee.model.group.GroupData;
import net.towee.model.group.GroupProfile;

public class GroupRolesShowerPresenter implements GroupRolesShower, RoleOperationHandler {

	public interface Display extends IsWidget {
		void showRole(Role r);
		
		HasRoleOperationHandlers getRoleOperationHandlers();

		void setDefaultRole(Role defaultRole);
	}
	
	// Injected
	private final Display display;
	private final RolesManager rolesManager;
	private final GroupsManager groupsManager;
	
	private GroupProfile group;
	
	@Inject
	public GroupRolesShowerPresenter(Display display, RolesManager manager, GroupsManager groupsManager) {
		this.display = display;
		this.rolesManager = manager;
		this.groupsManager = groupsManager;
		
		// Set handler
		display.getRoleOperationHandlers().addRoleOperationHandler(this);
	}
	
	private void setDefaultRole(Role role) {
		Preconditions.checkNotNull(role, "null role");
		Preconditions.checkArgument( !Strings.isNullOrEmpty(role.getId()), "null role id" );
		
		rolesManager.setDefaultRole(group.getId(), role, new AsyncCallback<Void>(){
			@Override
			public void onFailure(Throwable caught) {
			}
			@Override
			public void onSuccess(Void result) {
			}
		});
	}

	private void removeRole(Role role) {
		Preconditions.checkNotNull(role, "null role");
		Preconditions.checkArgument( !Strings.isNullOrEmpty(role.getId()), "null role id" );		
		
		rolesManager.removeRole(group.getId(), role, new AsyncCallback<Boolean>(){
			@Override
			public void onFailure(Throwable caught) {
			}
			@Override
			public void onSuccess(Boolean result) {
			}
		});
	}

	private void createRole(Role role) {
		Preconditions.checkNotNull(role, "null role");
		Preconditions.checkArgument( !Strings.isNullOrEmpty(role.getId()), "null role id" );
		Preconditions.checkArgument( !Strings.isNullOrEmpty(role.getName()), "null role name" );
		
		rolesManager.addRole(group.getId(), role, new AsyncCallback<Role>() {
			@Override
			public void onFailure(Throwable caught) {
			}
			@Override
			public void onSuccess(Role result) {
				display.showRole(result);
			}
		});
	}
	
	@Override
	public void go(HasWidgets container) {
		Preconditions.checkNotNull(group, "null group");
		container.clear();
		container.add( display.asWidget() );
		
		groupsManager.getGroupData(group.getId(), new AsyncCallback<GroupData>(){
			@Override
			public void onFailure(Throwable caught) {
			}
			@Override
			public void onSuccess(GroupData result) {
				for(Role r : result.getRoleContainer().getRoleList())
					display.showRole(r);

				display.setDefaultRole( result.getRoleContainer().getDefaultRole() );
			}
		});
	}

	@Override
	public void setGroupProfile(GroupProfile id) {
		this.group = id;
	}

	@Override
	public void onRoleOperation(RoleOperationEvent event) {
		switch( event.getEventType() ) {
		case ADD:
			createRole( event.getRole() );
			break;
		case REMOVE:
			removeRole( event.getRole() );
			break;
		case SET_DEFAULT:
			setDefaultRole( event.getRole() );
			break;
		}
	}
}
